"""
自定义分页组件
传入数据类型
django request 以及数据库查询结果queryset
可以自动生成分页结果
类 例
def pretty_list(request):
    #1.根据自己的情况取筛选自己的数据
    queryset = models.PrettyNum.objects.all()
    #2.利用实例化分页对象 进行传值
    page_object = Pagination(request, queryset)


    context = {
            'search_data': search_data, # 查询数据
            'page_queryset': page_object.page_queryset,  #分完也得数据
            'page_string': page_object.html(), # 生成的页码数据
    }

    return render(request, 'pretty_list.html', context)

在HTML页面中加入
                    <tbody>
                    {% for obj in page_queryset %}
                          <tr>
                            <th>{{ obj.id }}</th>
                            <td>{{ obj.mobile }}</td>
                            <th>{{ obj.price }}</th>
                            <td>{{ obj.get_level_display }}</td>
                            <td>{{ obj.get_status_display }}</td>
                            <td>
                                <a class="btn btn-primary" href="/pretty/{{ obj.id }}/edit/">编辑</a>
                                <a class="btn btn-danger" href="/pretty/{{ obj.id }}/del/">删除</a>
                            </td>
                          </tr>
                    {% endfor %}
                    </tbody>
        <ul class="pagination">
            {{ page_string }}

        </ul>
"""
from django.utils.safestring import mark_safe


class Pagination(object):
    """
    请求对象：request
    查询结果:queryset
    每页显示数据数量：pege_size
    URL中获取分页参数:page_param
    显示当前页的前几页或后几页:plus
    """
    def __init__(self, request, queryset, pege_size=5, page_param="page", plus=5):
        # 当前页码 转换成数字
        page = request.GET.get(page_param, "1")
        if page.isdecimal():
            page = int(page)
        else:
            page = 1
        # 初始化当前页码
        self.page = page
        # 初始化每页需要显示的信息数量
        self.pege_size = pege_size
        # 初始化当前数据开始条数
        self.start = (page - 1) * pege_size
        # 初始化当前数据结束条数
        self.end = page * pege_size
        print(page, type(page))
        self.page_queryset = queryset[self.start:self.end]
        # 统计数据总条数 取自上面queryset
        total_count = queryset.count()
        # 计算需要生成的页码数量 得到两个数
        total_page_count, div = divmod(total_count, pege_size)
        if div:
            total_page_count += 1
        # 实际得到的页码数
        self.total_page_count = total_page_count
        self.plus = plus

    def html(self):
        # 计算出当前显示前5页 后5页 不过多显示
        # 显示网页数量跨度
        plus = 5
        # 解决网页按钮为负数的问题
        if self.total_page_count <= 2 * plus + 1:
            # 起始跨度
            start_page = 1
            # 结束跨度
            end_page = self.total_page_count
        else:
            if self.page <= plus:
                start_page = 1
                end_page = 2 * plus + 1
            else:
                # 当前页 > 5
                if (self.page + plus) > self.total_page_count:
                    start_page = self.total_page_count - 2 * plus
                    end_page = self.total_page_count
                else:
                    # 起始跨度
                    start_page = self.page - plus
                    # 结束跨度
                    end_page = self.page + plus

        # 页码按钮数量
        page_str_list = []

        # 上一页按钮
        if self.page > 1:
            prev = f'<li><a href="?page={self.page - 1}">上一页</a></li>'
        else:
            prev = '<li><a href="?page=1">上一页</a></li>'
        page_str_list.append(prev)

        # 页码按钮
        for i in range(start_page, end_page + 1):
            if self.page == i:
                ele = f'<li class="active"><a href="?page={i}">{i}</a></li>'
                page_str_list.append(ele)
            else:
                ele = f'<li><a href="?page={i}">{i}</a></li>'
                page_str_list.append(ele)

        # 下一页按钮
        if self.page < self.total_page_count:
            prev = f'<li><a href="?page={self.page + 1}">下一页</a></li>'
        else:
            prev = f'<li><a href="?page={self.total_page_count}">下一页</a></li>'
        page_str_list.append(prev)
        # 代码转成成网页能识别的代码
        page_string = mark_safe(''.join(page_str_list))
        return page_string
